#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Author : gao
# Time : 2020/7/6 19:03

import SelectFeature as sf
import Shannon as sn
import numpy as np

'''
    创建决策时
'''

'''
    功能 : 返回数据集中出现最多的类别
    参数 ：类别列表
    返回 ：出现最多的类别
'''


def getMajorityClass(classList):
    classDict = {}
    max = -1
    lable = ''
    for c in classList:
        if c not in classDict.keys():
            classDict[c] = 1
        else:
            classDict[c] += 1
            if max < classDict[c]:
                max = classDict[c]
                lable = c
    # 判断是否全是1
    if lable == '':
        lable = classList[0]  # 此处可以改为随机，懒得写了
    return lable


'''
    功能：递归创建决策树
    参数：
        dataSet : 数据集
        labels : 数据集里每个数据的意义
        featureList : 存放最优属性的list
'''

'''
    功能 ：判断是否所有的数据的属性值全部相同
    参数 ：属性值集合（不包括类别）
    返回 ：是或否
'''


def determineSame(dataSet):
    # 转换成np的array获取转置矩阵再对每行进行统计
    dataSet = np.array(dataSet).T.tolist()
    for i in dataSet:
        if i.count(i[0]) != len(i):
            return False
    return True


'''
    功能： 创建决策shu
    参数：
        dataSet : 数据集（包含类别）
        labels : 数据集每列属性的含义
        bestFeatureList : 最优属性集合
'''

def createDecisionTree(dataSet: list, labels, bestFeatureList):
    # 获取最后的结果类别
    trainY = [d[-1] for d in dataSet]
    # 检查是否全部类别都是一样的
    if trainY.count(trainY[0]) == len(trainY):  # count 是统计有多少字
        return trainY[0]
    # 如果属性集为空或者在属性集上取值全部相同，这种情况没法分支了，
    # 返回dataSet中出现再多的类别
    if len(dataSet[0]) == 1 or determineSame(dataSet[:len(dataSet)-1]):
        return getMajorityClass(trainY)
    #选择最优属性进行划分
    bestFeature = sf.selectAxis(dataSet)
    bestFeatureLabel = labels[bestFeature]
    bestFeatureList.append(bestFeature)
    #用一个字典模拟树
    myTree = {bestFeatureLabel:{}}
    #去掉最优的属性->生成一个新的参数数组
    #del(labels[bestFeature]) #不应该删除的，递归回来就没了，到时候就数组越界了
    newLabelsArg = labels[:bestFeature]
    newLabelsArg.append(labels[bestFeature+1:])
    #生成最优属性的值的集合
    featureSet = set([d[bestFeature] for d in dataSet])
    for valueF in featureSet:
        newDataSetSplit = sf.splitDataSet(dataSet,bestFeature,valueF)
        myTree[bestFeatureLabel][valueF] = createDecisionTree(newDataSetSplit,newLabelsArg,bestFeatureList)
    return myTree



if __name__ == '__main__':
    dataSet,labels = sn.createDataSet()
    bestFeatureList = []
    print(createDecisionTree(dataSet,labels,bestFeatureList))